package org.dinqy.impl;

import java.util.ArrayList;
import java.util.List;

import org.dinqy.ClauseBean;
import org.dinqy.QueryExecutor;

/**
 * @author armandino (at) gmail.com
 */
abstract class ClauseNode<T> {
    private ClauseNode<T> parent;
    private ClauseNode<T> successor;
    private Class<T> entityClass;
    private ClauseBean clauseBean;
    private QueryExecutor<T> queryExecutor;
    
    protected ClauseNode(ClauseNode<T> parent) {
        this.parent = parent;
        if(parent != null) {
            this.entityClass = parent.entityClass;
            this.queryExecutor = parent.queryExecutor;
        }
    }
    
    final Class<T> getEntityClass() {
        return entityClass;
    }
    
    public final void setEntityClass(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
    
    final ClauseBean getClauseBean() {
        return clauseBean;
    }
    
    final void setClauseBean(ClauseBean clauseBean) {
        this.clauseBean = clauseBean;
    }
    
    final ClauseNode<T> getSuccessor() {
        return successor;
    }
    
    final void setSuccessor(ClauseNode<T> successor) {
        this.successor = successor;
    }
    
    final QueryExecutor<T> getQueryExecutor() {
        return queryExecutor;
    }
    
    public final void setQueryExecutor(QueryExecutor<T> queryExecutor) {
        this.queryExecutor = queryExecutor;
    }
    
    final List<ClauseBean> getClauseBeans() {
        final List<ClauseBean> clauseBeans = new ArrayList<ClauseBean>();
        final ClauseNode<T> root = getRootNode();
        for(ClauseNode<?> c = root; c != null; c = c.getSuccessor()) {
            ClauseBean clauseBean = c.getClauseBean();
            if(clauseBean != null) // TODO: refactor to avoid null check
                clauseBeans.add(c.getClauseBean());
        }
        return clauseBeans;
    }
    
    private ClauseNode<T> getRootNode() {
        ClauseNode<T> c = this;
        while(c.parent != null)
            c = c.parent;
        return c;
    }
    
}
